package model

import (
	"errors"
	"fmt"
	"server/share/config"
	"strings"

	"github.com/hwcer/cosgo/schema"
	"github.com/hwcer/cosgo/times"
	"github.com/hwcer/cosgo/values"
	"github.com/hwcer/updater"
	"github.com/hwcer/updater/dataset"
	"github.com/hwcer/updater/operator"
)

func init() {
	Register(&Daily{})
}

type TodayTask struct {
	Id      int32 `json:"id" bson:"id"`
	Flag    int32 `json:"flag" bson:"flag"` //1 已经完成
	Process int32 `json:"process" bson:"process"`
}

type Daily struct {
	History `bson:"inline"`
	Uid     string          `bson:"uid" json:"-"  index:"name:_idx_uid_primary,Sort:asc,Priority:99" `
	Viper   map[int32]int32 `bson:"viper" json:"viper,omitempty"` //月卡领取状况
	//Rmb           int32           `bson:"rmb" json:"rmb"`
	//Login         int32           `bson:"login" json:"login"`
	TodayTask     []*TodayTask    `bson:"todayTask" json:"todayTask,omitempty"`         //今天的每日任务
	RollDailyTask int32           `bson:"rollDailyTask" json:"rollDailyTask,omitempty"` //每日任务更换次数
	DailyProcess  []int32         `bson:"dailyProcess" json:"dailyProcess,omitempty"`   ////日任务进度
	EggTaskDel    int32           `bson:"eggTaskDelete" json:"eggTaskDelete,omitempty"` //放弃抓蛋限时任务次数
	EggTaskNum    map[int32]int32 `bson:"eggTaskNum" json:"eggTaskNum,omitempty"`       //每天完成蛋任务 id->num
	//EggTaskComplete []int32      `bson:"eggTaskComplete" json:"eggTaskComplete"`
	//ItemList         map[int32]EggPool `bson:"itemList" json:"itemList"`
	DailyBoss        int64           `bson:"dailyBoss" json:"dailyBoss,omitempty"`               //每日BOSS最大伤害量
	DailyBosddReward int32           `bson:"dailyBossdReward" json:"dailyBossdReward,omitempty"` //每日BOSS领取记录
	HookSNum         int32           `bson:"hookSNum" json:"hookSNum,omitempty"`                 //挂机加速购买记录
	FWboss           map[int32]int32 `bson:"fwboss" json:"fwboss,omitempty"`                     //好友BOSS ,星级->次数
	UseBossItem      int32           `bson:"useBossItem" json:"useBossItem,omitempty"`           //使用道具发现好友boss次数
	UseHelp          []string        `bson:"useHelp" json:"useHelp,omitempty"`                   //今日使用过的助阵列表
	TouchTime        int32           `bson:"touchTime" json:"touchTime,omitempty"`               //每天触摸主角次数
	CatcherPool      map[int32]int32 `bson:"catcherPool" json:"catcherPool,omitempty"`           //抓蛋 每日刷新次数
}

func (this *Daily) Get(k string) (any, bool) {
	if ik, ok := this.key(k); ok && ik > 0 {
		return this.Value[ik], true
	} else if ok {
		return 0, true
	}
	return nil, false
}

func (this *Daily) Set(k string, v any) (any, bool) {
	if ik, ok := this.key(k); ok && ik > 0 {
		r := dataset.ParseInt64(v)
		this.Value[ik] = r
		return r, true
	} else if ok {
		return 0, true
	}
	return v, false
}

// Reset 每次执行前检查一次数据是否有效
func (this *Daily) Reset(u *updater.Updater, last int64) bool {
	today := times.New(u.Now()).Daily(0).Now().Unix()
	return last < today
}

func (this *Daily) New(u *updater.Updater) any {
	d := &Daily{}
	d.IID, _ = times.New(u.Now()).Sign(0)
	d.Uid = u.Uid()
	d.OID = Unique(u, d.IID)
	d.Value = make(map[int32]int64)
	return d
}
func (this *Daily) Field(u *updater.Updater, iid int32) (string, error) {
	return fmt.Sprintf("value.%d", iid), nil
}

func (this *Daily) Schema() *schema.Schema {
	sch, _ := schema.Parse(this)
	return sch
}

func (this *Daily) IType(int32) int32 {
	return config.ITypeDaily
}

//func (this *Daily) TableOrder() int32 {
//	his := History{}
//	return his.TableOrder() - 1 //必须先让HIS 初始化
//}

func (this *Daily) Getter(u *updater.Updater, data *dataset.Document, keys []string) error {
	uid := u.Uid()
	if uid == "" {
		return errors.New("daily.Getter uid not found")
	}
	iid, _ := times.New(u.Now()).Sign(0)
	oid := Unique(u, iid)

	d := &Daily{Uid: u.Uid()}
	d.OID = oid
	d.IID = iid
	d.Value = make(map[int32]int64)
	tx := db.Omit("_id", "uid").Where(oid)
	if tx = tx.Find(d); tx.Error != nil {
		return tx.Error
	} else if tx.RowsAffected == 0 {
		if err := db.Create(d).Error; err != nil {
			return err
		}
	}
	if d.Value == nil {
		d.Value = map[int32]int64{}
	}
	data.Reset(d)
	//this.history(u, d)
	//塞一个空操作
	u.Dirty(&operator.Operator{OID: oid, IID: iid, Bag: config.ITypeDaily, Type: operator.TypesNew, Result: []any{d}})

	return nil
}

func (this *Daily) Setter(u *updater.Updater, data dataset.Update) error {
	uid := u.Uid()
	if uid == "" {
		return errors.New("Daily.Setter uid not found")
	}
	now, _ := times.New(u.Now()).Sign(0)
	oid := Unique(u, now)
	//
	//doc := u.Handle(config.ITypeDaily).(*updater.Document)
	//all := doc.Any().(*Daily)
	var up map[string]any = data
	//if len(all.Value) > 0 {
	//	up = data
	//} else {
	//	up = make(map[string]any)
	//	value := make(map[int32]int64)
	//	for k, v := range data {
	//		if ik, ok := this.key(k); ok && ik > 0 {
	//			value[ik] = dataset.ParseInt64(v)
	//		} else if !ok {
	//			up[k] = v
	//		}
	//	}
	//	if len(value) > 0 {
	//		up["value"] = value
	//	}
	//}
	tx := db.Model(this).Update(up, oid)
	return tx.Error
}

func (this *Daily) key(s string) (r int32, ok bool) {
	if strings.HasPrefix(s, "value.") {
		ok = true
		r = values.ParseInt32(strings.TrimPrefix(s, "value."))
	}
	return
}

// 新对象同步到历史数据
//func (this *Daily) history(u *updater.Updater, d *Daily) {
//	coll := u.Handle(config.ITypeHistory).(*updater.Collection)
//	if dt := coll.Dataset(); dt != nil {
//		dt.Receive(d.OID, &d.History)
//	}
//}
